//
//  PackageParser.m
//  Maze1
//
//  Created by Lin Tian on 9/19/11.
//  Copyright 2011 tina. All rights reserved.
//

#import "PackageParser.h"

#define NAMEMAXSIZE 32

static PackageParser *sharedSingleton = NULL;

@implementation PackageParser
@synthesize isFirstMsg;
@synthesize socket=_socket;
@synthesize scene;
@synthesize player;
@synthesize state;
@synthesize from;
@synthesize to;

/*+(id)initPackageParser
 {
 return [[PackageParser alloc] init];
 }*/

-(id)init
{
	if ((self = [super init])) {
		isFirstMsg = true;
		_socket = [[Socket alloc] init];
		if( _socket ) {
			if( ![_socket open:30000] )
				return nil;
		}
        from = [[Address alloc] init];
        to = [[Address alloc] initWithA:204 B:140 C:154 D:153 port:30000];
        state = PlayerStateNone;
        //roleType = map;
        _posScene = false;
        self.player = [LocalPlayer player];
        
        [[CCScheduler sharedScheduler] scheduleUpdateForTarget:self priority:2 paused:NO];
	}
	
	return self;
}

-(void)dealloc
{
	//scene = nil;
    [from release];
    from = nil;
    
    [to release];
    to = nil;
    
    [_socket release];
    _socket = nil;
    
    [player release];
    player = nil;
    
    [scene release];
    scene = nil;
    
    [[CCScheduler sharedScheduler] unscheduleUpdateForTarget:self];
	[super dealloc];
}

+(PackageParser*)sharedPackageParser
{
    @synchronized(self){
        if (sharedSingleton == NULL) {
            sharedSingleton = [[self alloc] init];
        }
    }
    return(sharedSingleton);
}

-(void)update:(ccTime)dt
{
    [self updateLocalState];
    [self updateServerState];
}


-(bool)updateLocalState
{
	char data[256];
    int index = 0;
    int received_bytes;
    while(true)
    {
        index = 0;
        received_bytes = [_socket receiveFrom:from data:data size:256];
        if (received_bytes <= 0) {
            break;
        }else {
            //the first msg will send a new port for further connection
            if (isFirstMsg) {
                [to changePortTo:from.port];
                isFirstMsg = false;
            }
            
            /********************  start to deal with the msg  **********************/
            unsigned int temp =0;
            memcpy(&temp, &data[index], sizeof(temp));
            index += sizeof(temp);
            switch (temp) {
                case PlayerStateNone:
                case PlayerStateLoggingIn:
                case PlayerStateLoggingOut:
                case PlayerStateCreatingRoom:
                case PlayerStateEnteringRoom:
                case PlayerStateStartingGame:
                {
                    break;
                }
                case PlayerStateInHall:
                {
                    [self receivePlayerStateInHallWith:data];
                    break;
                }
                case PlayerStateInRoom:
                {
                    [self receivePlayerStateInRoomWith:data];
                    break;
                }
                case PlayerStateLeavingRoom:
                {
                    [self receivePlayerStateLeavingRoomWith:data];
                    break;
                }
                case PlayerStateLoadingGame:
                {
                    [self receivePlayerStateLoadingGameWith:data];
                    break;
                }
                case PlayerStateInGame:
                {
                    [self receivePlayerStateInGameWith:data];
                    break;
                }
                case PlayerStateGameEnd:
                    //show game end screen
                    break;
                default:
                    break;
            }
            NSLog( @"packet received" );
        }
	}
    NSLog(@"didn't receive anything");
	
	return TRUE;
}

-(bool)updateServerState
{
    switch (state) {
        case PlayerStateLoggingIn:
        {
            [self sendLoginRequest];
            break;
        }
        case PlayerStateLoggingOut:
        {
            [self sendLogoutRequest];
            break;
        }
        case PlayerStateInHall:
        {
            [self sendPlayerStateInHall];
            break;
        }
        case PlayerStateCreatingRoom:
        {
            [self sendCreateRoomRequest];
            break;
        }
        case PlayerStateEnteringRoom:
        {
            [self sendEnterRoomInfo];
            break;
        }
        case PlayerStateInRoom:
        {
            [self sendplayerStateInRoom];
            break;
        }
        case PlayerStateLoadingGame:
        {
            [self sendGameLoadingProgress];
            break;
        }
        case PlayerStateLoadingGameComplete:
        {
            [self sendGameLoadingComplete];
            break;
        }
        case PlayerStateStartingGame:
        {
            [self sendStartGameRequest];
            break;
        }
        case PlayerStateInGame:
        {
            [self sendPlayerStateInGame];
            break;
        }
        case PlayerStateGameEnd:
        {
            [self sendGameOverRequest];
            break;
        }
        default:
            break;
    }
    //NSLog( @"packet received" );
	return TRUE;
    
}

-(bool)receivePlayerStateInHallWith:(char*)data
{
    int index = sizeof(msgType);
    if (state == PlayerStateLoggingIn || state == PlayerStateInRoom) {
        state = PlayerStateInHall;
        
        unsigned int playerId;
        memcpy(&playerId,&data[index],sizeof(playerId));
        index += sizeof(playerId);
        self.player.playerId = playerId;
        
        unsigned int numRooms = 0;
        memcpy(&numRooms, &data[index], sizeof(numRooms));
        index += sizeof(numRooms);
        
        Room* aRoom;
        unsigned int roomId = 0;
        unsigned char capacity = 0;
        unsigned char currentNumPlayers = 0;
        unsigned char numForces = 0;
        unsigned int map = 0;
        
        NSMutableArray* roomList = [NSMutableArray array];
        
        for (int i = 0; i < numRooms; i++) {
            memcpy(&roomId, &data[index], sizeof(roomId));
            index += sizeof(roomId);
            
            memcpy(&capacity, &data[index], sizeof(capacity));
            index += sizeof(capacity);
            
            memcpy(&currentNumPlayers, &data[index], sizeof(currentNumPlayers));
            index += sizeof(currentNumPlayers);
            
            memcpy(&numForces, &data[index], sizeof(numForces));
            index += sizeof(numForces);
            
            memcpy(&map, &data[index], sizeof(map));
            index += sizeof(map);
            
            aRoom = [[Room alloc] initWithRoomId:roomId];
            aRoom.capacity = capacity;
            aRoom.currentNumPlayers = currentNumPlayers;
            aRoom.numForces = numForces;
            aRoom.mapId = map;
            
            [roomList addObject:aRoom];
            [aRoom release];
        }
        
        //Login* aLayer = (Login*)[[CCDirector sharedDirector].runningScene getChildByTag:1];
        //[aLayer changeSceneTo:[RoomList sceneWithRoomList:roomList]];
        self.scene = [RoomList sceneWithRoomList:roomList];
        [[CCDirector sharedDirector] replaceScene:self.scene];
    }else if(state == PlayerStateInHall)
    {
        unsigned int playerId;
        memcpy(&playerId,&data[index],sizeof(playerId));
        index += sizeof(playerId);
        self.player.playerId = playerId;
        
        unsigned int numRooms = 0;
        memcpy(&numRooms, &data[index], sizeof(numRooms));
        index += sizeof(numRooms);
        
        Room* aRoom;
        unsigned int roomId = 0;
        unsigned char capacity = 0;
        unsigned char currentNumPlayers = 0;
        unsigned char numForces = 0;
        unsigned int map = 0;
        
        RoomList *aPage =(RoomList*)[(CCScene*)scene getChildByTag:ROOMLISTPAGE];
        NSMutableArray* roomList = [NSMutableArray array];
        
        for (int i = 0; i < numRooms; i++) {
            memcpy(&roomId, &data[index], sizeof(roomId));
            index += sizeof(roomId);
            
            memcpy(&capacity, &data[index], sizeof(capacity));
            index += sizeof(capacity);
            
            memcpy(&currentNumPlayers, &data[index], sizeof(currentNumPlayers));
            index += sizeof(currentNumPlayers);
            
            memcpy(&numForces, &data[index], sizeof(numForces));
            index += sizeof(numForces);
            
            memcpy(&map, &data[index], sizeof(map));
            index += sizeof(map);
            
            aRoom = [[Room alloc] initWithRoomId:roomId];
            aRoom.capacity = capacity;
            aRoom.currentNumPlayers = currentNumPlayers;
            aRoom.numForces = numForces;
            aRoom.mapId = map;
            
            [roomList addObject:aRoom];
            [aRoom release];
        }
        aPage.roomPool = roomList;
    }
    
    NSLog( @"%s packet received:", __PRETTY_FUNCTION__);
    return true;
}

-(bool)receivePlayerStateInRoomWith:(char *)data
{
    int index = sizeof(msgType);
    
    unsigned int roomId;
    memcpy(&roomId, &data[index], sizeof(roomId));
    index += sizeof(roomId);
    
    unsigned char capacity;
    memcpy(&capacity, &data[index], sizeof(capacity));
    index += sizeof(capacity);
    
    unsigned char numForces;
    memcpy(&numForces, &data[index], sizeof(numForces));
    index += sizeof(numForces);
    
    unsigned int map;
    memcpy(&map, &data[index], sizeof(map));
    index += sizeof(map);
    
    unsigned int hostId;
    memcpy(&hostId, &data[index], sizeof(hostId));
    index += sizeof(hostId);
    
    unsigned char playerNum;
    memcpy(&playerNum, &data[index], sizeof(playerNum));
    index += sizeof(playerNum);
    
    if (state == PlayerStateCreatingRoom) {
        Room* aRoom = self.player.room;
        aRoom.roomId = roomId;
        aRoom.capacity = capacity;
        //whether to change depands on whether can players other than owner can change the number of forces
        aRoom.numForces = numForces;
        
        unsigned int playerId;
        unsigned int nameSize;
        char name[NAMEMAXSIZE];
        unsigned char forceId;
        msgType playerCurrentState;
        
        for (int i = 0; i < playerNum; i++) {
            memset(&name, 0, NAMEMAXSIZE);
            
            memcpy(&playerId, &data[index], sizeof(playerId));
            index += sizeof(playerId);
            
            memcpy(&nameSize, &data[index], sizeof(nameSize));
            index += sizeof(nameSize);
            
            memcpy(&name, &data[index], sizeof(char)*nameSize);
            index += sizeof(char)*nameSize;
            
            memcpy(&forceId, &data[index], sizeof(forceId));
            index += sizeof(forceId);
            
            memcpy(&playerCurrentState, &data[index], sizeof(playerCurrentState));
            index += sizeof(playerCurrentState);
            
            if (self.player.playerId == playerId) {
                continue;
            }
            
            //add other player into the room
            Player *other = [Player playerWithPlayerId:playerId name:[NSString stringWithUTF8String: name]];
            [aRoom joinRoomWithPlayer:other];
        }
        state = PlayerStateInRoom;
        [[CCDirector sharedDirector] replaceScene:[RoomInfo sceneWithRoom:aRoom]];
    }else if(state == PlayerStateEnteringRoom)
    {
        Room* aRoom = self.player.room;
        aRoom.roomId = roomId;
        aRoom.capacity = capacity;
        aRoom.numForces = numForces;
        
        unsigned int playerId;
        unsigned int nameSize;
        char name[NAMEMAXSIZE];
        unsigned char forceId;
        msgType playerCurrentState;
        
        for (int i = 0; i < playerNum; i++) {
            memset(&name, 0, NAMEMAXSIZE);
            
            memcpy(&playerId, &data[index], sizeof(playerId));
            index += sizeof(playerId);
            
            memcpy(&nameSize, &data[index], sizeof(nameSize));
            index += sizeof(nameSize);
            
            memcpy(&name, &data[index], sizeof(char)*nameSize);
            index += sizeof(char)*nameSize;
            
            memcpy(&forceId, &data[index], sizeof(forceId));
            index += sizeof(forceId);
            
            memcpy(&playerCurrentState, &data[index], sizeof(playerCurrentState));
            index += sizeof(playerCurrentState);
            
            if (self.player.playerId == playerId) {
                continue;
            }
            
            //add other player into the room
            
            Player *other = [Player playerWithPlayerId:playerId name:[NSString stringWithUTF8String: name]];
            if (playerId == hostId) {
                aRoom.owner = other;
                other.room = aRoom;
            }else
            {
                [aRoom joinRoomWithPlayer:other];
            }
        }
        state = PlayerStateInRoom;
        [[CCDirector sharedDirector] replaceScene:[RoomInfo sceneWithRoom:aRoom]];
    }else if(state == PlayerStateInRoom)
    {
        //do I still need to check these infos?
        Room* aRoom = self.player.room;
        aRoom.roomId = roomId;
        aRoom.capacity = capacity;
        aRoom.numForces = numForces;
        
        if (aRoom.owner.playerId != hostId) {
            NSLog(@"the owner changed, room should be closed");
        }
        
        unsigned int playerId;
        unsigned int nameSize;
        char name[NAMEMAXSIZE];
        unsigned char forceId;
        msgType playerCurrentState;
        
        for (int i = 0; i < playerNum; i++) {
            memset(&name, 0, NAMEMAXSIZE);
            
            memcpy(&playerId, &data[index], sizeof(playerId));
            index += sizeof(playerId);
            
            memcpy(&nameSize, &data[index], sizeof(nameSize));
            index += sizeof(nameSize);
            
            memcpy(&name, &data[index], sizeof(char)*nameSize);
            index += sizeof(char)*nameSize;
            
            memcpy(&forceId, &data[index], sizeof(forceId));
            index += sizeof(forceId);
            
            memcpy(&playerCurrentState, &data[index], sizeof(playerCurrentState));
            index += sizeof(playerCurrentState);
            
            if (self.player.playerId == playerId) {
                continue;
            }
            
            //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!HAVENT DONE YET
            //add other player into the room
            Player* other = nil;
            if ((other = [aRoom findPlayerWithPlayerId:playerId])) {
                //change the value of numforces
                
            }else
            {
                Player *other = [Player playerWithPlayerId:playerId name:[NSString stringWithUTF8String: name]];
                [aRoom joinRoomWithPlayer:other];
            }
        }
    }
    
    NSLog( @"%s packet received:", __PRETTY_FUNCTION__);
    return YES;
}

-(bool)receivePlayerStateLeavingRoomWith:(char *)data
{
    int index = sizeof(msgType);
    
    if (state == PlayerStateInRoom) {
        unsigned int roomId;
        memcpy(&roomId, &data[index], sizeof(roomId));
        index += sizeof(roomId);
        
        unsigned int playerId;
        memcpy(&playerId, &data[index], sizeof(playerId));
        index += sizeof(playerId);
        
        unsigned char posInRoom;
        memcpy(&posInRoom, &data[index], sizeof(posInRoom));
        index += sizeof(posInRoom);
        
        //what should I do here???
    }
    
    NSLog( @"%s packet received:", __PRETTY_FUNCTION__);
    return YES;
}

-(bool)receivePlayerStateLoadingGameWith:(char *)data
{
    int index = sizeof(msgType);
    
    if (state == PlayerStateInRoom || state == PlayerStateStartingGame) {
        [[CCDirector sharedDirector] replaceScene:[Loading scene]];
        ((Loading*)[(CCScene*)[[CCDirector sharedDirector] runningScene] getChildByTag:LoadingPage]).player = self.player;
        
        HelloWorldLayer* game = [[HelloWorldLayer alloc] init];
        //game.visible = NO;
        self.player.loadingProgress = 20;
        
        unsigned int numPlayer = 0;
        memcpy(&numPlayer,&data[index], sizeof(numPlayer));
        index += sizeof(numPlayer);
        
        Room* aRoom = self.player.room;
        game.room = aRoom;
        Player* other = nil;
        for (int i = 0; i < numPlayer; i++) {
            unsigned int playerId = 0;
            memcpy(&playerId,&data[index], sizeof(playerId));
            index += sizeof(playerId);
            
            float posX = 0;
            memcpy(&posX,&data[index], sizeof(posX));
            index += sizeof(posX);
            
            float posY = 0;
            memcpy(&posY,&data[index], sizeof(posY));
            index += sizeof(posY);
            
            //havent deal with appearance yet,need to do it some day
            unsigned int appearance = 0;
            memcpy(&appearance,&data[index], sizeof(appearance));
            index += sizeof(appearance);
            
            //need to show the progress, haven't done!!
            unsigned int loadingProgress = 0;
            memcpy(&loadingProgress, &data[index], sizeof(loadingProgress));
            index += sizeof(loadingProgress);
            
            if (self.player.playerId == playerId) {
                [self.player initSpriteWithParentNode:game position:ccp(posX, posY)];
                [game setViewpointCenter:self.player.position];
                game.player = self.player;
            }else
            {
                if ((other = [aRoom findPlayerWithPlayerId:playerId])) {
                    other.loadingProgress = loadingProgress;
                    //need to add appearance
                    
                    [game.remotePlayerList addObject:other];
                    [other initSpriteWithParentNode:game position:ccp(posX, posY)];
                }else
                {
                    NSLog(@"the player is not in this room!!");
                }
            }
            self.player.loadingProgress += 80/numPlayer;
        }
        self.scene = game;
        [game release];
        game = nil;
        self.player.loadingProgress = 100;
        state = PlayerStateLoadingGameComplete;
    }else if(state == PlayerStateLoadingGameComplete)
    {
        //update other players progress
    }
    
    NSLog( @"%s packet received:", __PRETTY_FUNCTION__);
    return YES;
}

-(bool)receivePlayerStateInGameWith:(char *)data
{
    int index = sizeof(msgType);
    
    if (state == PlayerStateLoadingGameComplete) {
        [[CCDirector sharedDirector] replaceScene:[HelloWorldLayer sceneWithGame:(HelloWorldLayer*)self.scene]];
        state = PlayerStateInGame;
    }else if(state == PlayerStateInGame)
    {
        //if it runs here, which means players are all in games already
        unsigned int roleType = 0;
        memcpy(&roleType, &data[index], sizeof(roleType));
        index += sizeof(roleType);
        switch (roleType) {
            case InGameTypeMap:
            {
                //actually, I have no idea why this is here.
                break;
            }
            case InGameTypePlayer:
            {
                unsigned int numPlayer = 0;
                memcpy(&numPlayer,&data[index], sizeof(numPlayer));
                index += sizeof(numPlayer);
                
                NSMutableArray* remotePlayers = ((HelloWorldLayer*)self.scene).remotePlayerList;
                Player* aPlayer = nil;
                for (int i = 0; i < numPlayer; i++) {
                    unsigned int playerId = 0;
                    memcpy(&playerId,&data[index], sizeof(playerId));
                    index += sizeof(playerId);
                    
                    unsigned char isCorrection;
                    memcpy(&isCorrection, &data[index], sizeof(isCorrection));
                    index += sizeof(isCorrection);
                    
                    unsigned int timeStamp = 0;
                    memcpy(&timeStamp, &data[index], sizeof(timeStamp));
                    index += sizeof(timeStamp);
                    
                    float posX = 0;
                    memcpy(&posX,&data[index], sizeof(posX));
                    index += sizeof(posX);
                    
                    float posY = 0;
                    memcpy(&posY,&data[index], sizeof(posY));
                    index += sizeof(posY);
                    
                    float velX = 0;
                    memcpy(&velX, &data[index], sizeof(velX));
                    index += sizeof(velX);
                    
                    float velY = 0;
                    memcpy(&velY, &data[index], sizeof(velY));
                    index += sizeof(velY);
                    
                    unsigned int itemOne = 0;
                    memcpy(&itemOne,&data[index], sizeof(itemOne));
                    index += sizeof(itemOne);
                    
                    unsigned int itemTwo = 0;
                    memcpy(&itemTwo,&data[index], sizeof(itemTwo));
                    index += sizeof(itemTwo);
                    
                    unsigned int appearance = 0;
                    memcpy(&appearance,&data[index], sizeof(appearance));
                    index += sizeof(appearance);
                    
                    if (self.player.playerId == playerId) {
                        if (isCorrection) {
                            self.player.position = CGPointMake(posX, posY);
                            self.player.speed = CGPointMake(velX, velY);
                        }
                    }else
                    {
                        for (int i = 0; i < [remotePlayers count]; i++) {
                            aPlayer = (Player*)[remotePlayers objectAtIndex:i];
                            if (aPlayer.playerId == playerId) {
                                aPlayer.position = CGPointMake(posX, posY);
                                aPlayer.speed = CGPointMake(velX, velY);
                                //[remotePlayers removeObject:aPlayer];
                                break;
                            }
                        }
                    }
                }
                break;
            }
            default:
                break;
        }
    }
    
    NSLog( @"%s packet received:", __PRETTY_FUNCTION__);
    return YES;
}

-(bool)sendLoginRequest
{
	char data[256] = { 0 };
    int index = 0;
    
    //start fill in data
    msgType playerState = PlayerStateLoggingIn;
    memcpy(&data[index], &playerState, sizeof(playerState));
    index += sizeof(playerState);
    
    unsigned char nameSize = [player.name length];
    memcpy(&data[index], &nameSize, sizeof(nameSize));
    index += sizeof(nameSize);
    
    const char *nameString = [player.name UTF8String];
    memcpy(&data[index], (void*)nameString, nameSize*sizeof(char));
    index += nameSize*sizeof(char);
    
    unsigned char pwdSize = [player.pwd length];
    memcpy(&data[index], &pwdSize, sizeof(pwdSize));
    index += sizeof(pwdSize);
    
    const char *pwdString = [player.pwd UTF8String];
    memcpy(&data[index], (void*)pwdString, pwdSize*sizeof(char));
    index += pwdSize*sizeof(char);
    
    if( [_socket sendTo:to data:&data[0] size:256] ) {
		NSLog( @"%s packet sent", __PRETTY_FUNCTION__);
        return YES;
	}
    return NO;
}

-(bool)sendLogoutRequest
{
    //Address * to = [[Address alloc] initWithA:192 B:168 C:1 D:106 port:30000];
	char data[256] = { 0 };
    int index = 0;
    
    //start fill in data
    msgType playerState = PlayerStateLoggingIn;
    memcpy(&data[index], &playerState, sizeof(playerState));
    index += sizeof(playerState);
    
    unsigned int playerId = self.player.playerId;
    memcpy(&data[index], &playerId, sizeof(playerId));
    index += sizeof(playerId);
    
    if( [_socket sendTo:to data:&data[0] size:256] ) {
		NSLog( @"%s packet sent", __PRETTY_FUNCTION__);
        return YES;
	}
    
    //[to release];
    return NO;
}

-(bool)sendPlayerStateInHall
{
    //Address * to = [[Address alloc] initWithA:207 B:151 C:240 D:177 port:30000];
	char data[256] = { 0 };
    int index = 0;
    
    //start fill in data
    msgType playerState = PlayerStateInHall;
    memcpy(&data[index], &playerState, sizeof(playerState));
    index += sizeof(playerState);
    
    unsigned int playerId = self.player.playerId;
    memcpy(&data[index], &playerId, sizeof(playerId));
    index += sizeof(playerId);
    
    if( [_socket sendTo:to data:&data[0] size:256] ) {
		NSLog( @"%s packet sent", __PRETTY_FUNCTION__);
        return YES;
	}
    
    //[to release];
    return NO;
}

-(bool)sendCreateRoomRequest
{
    //Address * to = [[Address alloc] initWithA:192 B:168 C:1 D:106 port:30000];
	char data[256] = { 0 };
    int index = 0;
    
    //start fill in data
    msgType playerState = PlayerStateCreatingRoom;
    memcpy(&data[index], &playerState, sizeof(playerState));
    index += sizeof(playerState);
    
    unsigned int playerId = self.player.playerId;
    memcpy(&data[index], &playerId, sizeof(playerId));
    index += sizeof(playerId);
    
    unsigned int mapId = self.player.room.mapId;
    memcpy(&data[index], &mapId, sizeof(mapId));
    index += sizeof(mapId);
    
    unsigned char numForces = self.player.room.numForces;
    memcpy(&data[index], &numForces, sizeof(numForces));
    index += sizeof(numForces);
    
    if( [_socket sendTo:to data:&data[0] size:256] ) {
		NSLog( @"%s packet sent", __PRETTY_FUNCTION__);
        return YES;
	}
    
    //[to release];
    return NO;
}

-(bool)sendLeaveRoomRequest
{
    //Address * to = [[Address alloc] initWithA:192 B:168 C:1 D:106 port:30000];
	char data[256] = { 0 };
    int index = 0;
    
    //start fill in data
    msgType playerState = PlayerStateLeavingRoom;
    memcpy(&data[index], &playerState, sizeof(playerState));
    index += sizeof(playerState);
    
    unsigned int playerId = self.player.playerId;
    memcpy(&data[index], &playerId, sizeof(playerId));
    index += sizeof(playerId);
    
    unsigned int roomId = self.player.room.roomId;
    memcpy(&data[index], &roomId, sizeof(roomId));
    index += sizeof(roomId);
    
    if( [_socket sendTo:to data:&data[0] size:256] ) {
		NSLog( @"%s packet sent", __PRETTY_FUNCTION__);
        return YES;
	}
    
    //[to release];
    return NO;
}

-(bool)sendEnterRoomInfo
{
    //Address * to = [[Address alloc] initWithA:192 B:168 C:1 D:106 port:30000];
	char data[256] = { 0 };
    int index = 0;
    
    //start fill in data
    msgType playerState = PlayerStateEnteringRoom;
    memcpy(&data[index], &playerState, sizeof(playerState));
    index += sizeof(playerState);
    
    unsigned int playerId = self.player.playerId;
    memcpy(&data[index], &playerId, sizeof(playerId));
    index += sizeof(playerId);
    
    unsigned int roomId = self.player.room.roomId;
    memcpy(&data[index], &roomId, sizeof(roomId));
    index += sizeof(roomId);
    
    if( [_socket sendTo:to data:&data[0] size:256] ) {
		NSLog( @"%s packet sent", __PRETTY_FUNCTION__);
        return YES;
	}
    
    //[to release];
    return NO;
}

-(bool)sendplayerStateInRoom
{
    //Address * to = [[Address alloc] initWithA:192 B:168 C:1 D:106 port:30000];
	char data[256] = { 0 };
    int index = 0;
    
    //start fill in data
    msgType playerState = PlayerStateInRoom;
    memcpy(&data[index], &playerState, sizeof(playerState));
    index += sizeof(playerState);
    
    unsigned int playerId = self.player.playerId;
    memcpy(&data[index], &playerId, sizeof(playerId));
    index += sizeof(playerId);
    
    unsigned int roomId = self.player.room.roomId;
    memcpy(&data[index], &roomId, sizeof(roomId));
    index += sizeof(roomId);
    
    unsigned int forceId = self.player.forceId;
    memcpy(&data[index], &forceId, sizeof(forceId));
    index += sizeof(forceId);
    
    if( [_socket sendTo:to data:&data[0] size:256] ) {
		NSLog( @"%s packet sent", __PRETTY_FUNCTION__);
        return YES;
	}
    
    //[to release];
    return NO;
}

-(bool)sendStartGameRequest
{
    //Address * to = [[Address alloc] initWithA:192 B:168 C:1 D:106 port:30000];
	char data[256] = { 0 };
    int index = 0;
    
    //start fill in data
    msgType playerState = PlayerStateStartingGame;
    memcpy(&data[index], &playerState, sizeof(playerState));
    index += sizeof(playerState);
    
    unsigned int playerId = self.player.playerId;
    memcpy(&data[index], &playerId, sizeof(playerId));
    index += sizeof(playerId);
    
    unsigned int roomId = self.player.room.roomId;
    memcpy(&data[index], &roomId, sizeof(roomId));
    index += sizeof(roomId);
    
    if( [_socket sendTo:to data:&data[0] size:256] ) {
		NSLog( @"%s packet sent", __PRETTY_FUNCTION__);
        return YES;
	}
    
    //[to release];
    return NO;
}

-(bool)sendGameLoadingProgress
{
    //Address * to = [[Address alloc] initWithA:192 B:168 C:1 D:106 port:30000];
	char data[256] = { 0 };
    int index = 0;
    
    //start fill in data
    msgType playerState = PlayerStateLoadingGame;
    memcpy(&data[index], &playerState, sizeof(playerState));
    index += sizeof(playerState);
    
    unsigned int playerId = self.player.playerId;
    memcpy(&data[index], &playerId, sizeof(playerId));
    index += sizeof(playerId);
    
    unsigned char loadingProgress = self.player.loadingProgress;
    memcpy(&data[index], &loadingProgress, sizeof(loadingProgress));
    index += sizeof(loadingProgress);
    
    if( [_socket sendTo:to data:&data[0] size:256] ) {
		NSLog( @"%s packet sent", __PRETTY_FUNCTION__);
        return YES;
	}
    
    //[to release];
    return NO;
}

-(bool)sendGameLoadingComplete
{
    //Address * to = [[Address alloc] initWithA:192 B:168 C:1 D:106 port:30000];
	char data[256] = { 0 };
    int index = 0;
    
    //start fill in data
    msgType playerState = PlayerStateLoadingGameComplete;
    memcpy(&data[index], &playerState, sizeof(playerState));
    index += sizeof(playerState);
    
    unsigned int playerId = self.player.playerId;
    memcpy(&data[index], &playerId, sizeof(playerId));
    index += sizeof(playerId);
    
    if( [_socket sendTo:to data:&data[0] size:256] ) {
		NSLog( @"%s packet sent", __PRETTY_FUNCTION__);
        return YES;
	}
    
    //[to release];
    return NO;
}


-(bool)sendPlayerStateInGame
{
	//Address * to = [[Address alloc] initWithA:192 B:168 C:1 D:106 port:30000];
	char data[256] = { 0 };
	int index = 0;
    
    //fill in the data
    msgType playerState = PlayerStateInGame;
    memcpy(&data[index], &playerState, sizeof(playerState));
    index += sizeof(playerState);
    
    unsigned int playerId = self.player.playerId;
    memcpy(&data[index], &playerId, sizeof(playerId));
    index += sizeof(playerId);
    
    unsigned int roomId = self.player.room.roomId;
    memcpy(&data[index], &roomId, sizeof(roomId));
    index += sizeof(roomId);
    
    unsigned int forceId = self.player.forceId;
    memcpy(&data[index], &forceId, sizeof(forceId));
    index += sizeof(forceId);
    
    //I haven't set the timeStamp
    unsigned int timeStamp = 0;
    memcpy(&data[index], &timeStamp, sizeof(timeStamp));
    index += sizeof(timeStamp);
	
	float posX = player.position.x;
	memcpy(&data[index], &posX, sizeof(posX));
    index += sizeof(posX);
	
	float posY = player.position.y;
	memcpy(&data[index], &posY, sizeof(posY));
    index += sizeof(posY);
	
	float velX = player.speed.x;
	memcpy(&data[index], &velX, sizeof(velX));
    index += sizeof(velX);
	
	float velY = player.speed.y;
	memcpy(&data[index], &velY, sizeof(velY));
    index += sizeof(velY);
    
    //haven't deal with item
	
	if( [_socket sendTo:to data:&data[0] size:256] ) {
		NSLog( @"%s packet sent", __PRETTY_FUNCTION__);
	}
	//[to release];
	
	return TRUE;
}

-(bool)sendGameOverRequest
{
    //Address * to = [[Address alloc] initWithA:192 B:168 C:1 D:106 port:30000];
	char data[256] = { 0 };
    int index = 0;
    
    //start fill in data
    msgType playerState = PlayerStateGameEnd;
    memcpy(&data[index], &playerState, sizeof(playerState));
    index += sizeof(playerState);
    
    unsigned int playerId = self.player.playerId;
    memcpy(&data[index], &playerId, sizeof(playerId));
    index += sizeof(playerId);
    
    if( [_socket sendTo:to data:&data[0] size:256] ) {
		NSLog( @"%s packet sent", __PRETTY_FUNCTION__);
        return YES;
	}
    
    //[to release];
    return NO;
}

@end
